﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;

namespace MPMovieCatalog.Forms.Grid
{
    public class SortableBindingList<T> : BindingList<T>
    {
            private ListSortDirection m_sortDirection;

            private PropertyDescriptor m_sortProperty = null;

            private bool m_isSorted = false;

            private Comparison<T> m_sorter = null;

            public SortableBindingList(ArrayList list)
            {
                foreach (T listItem in list)
                {
                    Add(listItem);
                }

                ListChanged += ListChangedHandler;

                m_sorter = new Comparison<T>(CompareMovies);
            }

            protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
            {
                m_sortDirection = direction;
                m_sortProperty = prop;
                m_isSorted = true;

                ((List<T>)Items).Sort(m_sorter);

                OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
            }

            protected override void RemoveSortCore()
            {
                m_sortDirection = ListSortDirection.Ascending;
                m_sortProperty = null;
                m_isSorted = false;

                ((List<T>)Items).Sort();
            }

            protected override bool SupportsSortingCore
            {
                get
                {
                    return true;
                }
            }

            protected override ListSortDirection SortDirectionCore
            {
                get
                {
                    return m_sortDirection;
                }
            }

            protected override PropertyDescriptor SortPropertyCore
            {
                get
                {
                    return m_sortProperty;
                }
            }

            protected override bool IsSortedCore
            {
                get
                {
                    return m_isSorted;
                }
            }

            private void ListChangedHandler(Object sender, ListChangedEventArgs e)
            {
                if (e.ListChangedType == ListChangedType.ItemAdded && m_isSorted)
                {
                    ApplySortCore(m_sortProperty, m_sortDirection);
                }
            }

            public int CompareMovies(T entity1, T entity2)
            {
                object prop1 = m_sortProperty.GetValue(entity1);
                object prop2 = m_sortProperty.GetValue(entity2);
                if (prop1 is IComparable && prop2 is IComparable)
                {
                    if (m_sortDirection == ListSortDirection.Ascending)
                    {
                        return CompareCamparables((IComparable)prop1, (IComparable)prop2);
                    }
                    else
                    {
                        return CompareCamparables((IComparable)prop2, (IComparable)prop1);
                    }
                }

                return 0;
            }

            private int CompareCamparables(IComparable c1, IComparable c2)
            {
                if (c1 == null)
                {
                    if (c2 == null)
                    {
                        return 0;
                    }
                    else
                    {
                        return -1;
                    }
                }
                else
                {
                    if (c2 == null)
                    {
                        return 1;
                    }
                    else
                    {
                        return c1.CompareTo(c2);
                    }
                }
            }
    }
}
